﻿using System;
using System.Collections.Generic;

namespace iStudio.Structure.Message
{
    public class MessageServer :IObservable<Message>
    {
        private static MessageServer _instance;

        public static MessageServer Instance
        {
            get
            {
                return _instance ?? (_instance = new MessageServer ());
            }
        }

        private class Unsubscriber : IDisposable
        {
            private readonly List<IObserver<Message>> _observers;
            private readonly IObserver<Message> _observer;

            public Unsubscriber (List<IObserver<Message>> observers, IObserver<Message> observer)
            {
                _observers = observers;
                _observer = observer;
            }

            public void Dispose ()
            {
                if ( (_observer != null) && (_observers.Contains(_observer)))
                {
                    _observers.Remove (_observer);
                }
            }
        }

        private readonly List<IObserver<Message>> _observers;

        private MessageServer ()
        {
            _observers = new List<IObserver<Message>> ();
        }

        public IDisposable Subscribe (IObserver<Message> observer)
        {
            if (!_observers.Contains (observer))
            {
                _observers.Add (observer);
            }

            return new Unsubscriber (_observers, observer);
        }

        public void Push (Message msg)
        {
            if (msg == null)
            {
                return;
            }

             foreach (IObserver<Message> observer in _observers)
             {
                observer.OnNext (msg);
             }
        }

        public void Clear ()
        {
            foreach (IObserver<Message> observer in _observers.ToArray ())
            {
                if (_observers.Contains (observer))
                {
                    observer.OnCompleted ();
                }
            }

            _observers.Clear ();
        }
    }
}
